package arithmetic.leetCode;

/**
 * @author dycong
 * @date 2019/9/25 9:05
 * 能够排除首部的空格，从第一个非空字符开始计算
 * <p>
 * 允许数字以正负号(+-)开头
 * <p>
 * 遇到非法字符便停止转换，返回当前已经转换的值，如果开头就是非法字符则返回0
 * <p>
 * 在转换结果溢出时返回特定值，这里是最大/最小整数
 * 同时,这里有一个常识性问题,字符char的ASCII相差的值,对于数值来说是相等的，这可以简化程序。
 * 比如:
 * <p>
 * '9' - '2' = 7
 * '7' - '3' = 4
 */
public class Atoi_8 {

    public static void main(String[] args) {
        System.out.println(myAtoi("9223372036854775808"));
    }

    public static int myAtoi(String str) {
        str = str.trim();
        long res = 0;
        char[] chars = str.toCharArray();
        boolean isPositive = true;

        for (int i = 0; i < chars.length; i++) {
            char s = chars[i];
            if (i == 0 && ((s == '-') || (s == '+'))) {
                isPositive = (s == '+');
            } else if (s >= '0' && s <= '9') {
                res = res * 10 + (s - '0');
                // 这个地方必须交验 溢出 ，不然可能会存在 超出 Long 返回的情况，数字就回不准确了
                long rest = isPositive ? res : -res;
                if (rest > Integer.MAX_VALUE) {
                    return Integer.MAX_VALUE;
                } else if (rest < Integer.MIN_VALUE) {
                    return Integer.MIN_VALUE;
                }
            } else {
                break;
            }
        }

        res = isPositive ? res : -res;
        return (int) res;

    }

    /**
     * long 型溢出
     *
     * @param str
     * @return
     */
    public static int myAtoi2(String str) {
        str = str.trim();
        long res = 0;
        char[] chars = str.toCharArray();
        boolean isPositive = true;

        for (int i = 0; i < chars.length; i++) {
            char s = chars[i];

            if (i == 0 && ((s == '-') || (s == '+'))) {
                isPositive = (s == '+');
            } else if (s >= '0' && s <= '9') {
                res = res * 10 + (s - '0');
            } else {
                break;
            }
        }
        if (!isPositive) {
            res = -res;
        }
        if (res > Integer.MAX_VALUE) {
            return Integer.MAX_VALUE;
        } else if (res < Integer.MIN_VALUE) {
            return Integer.MIN_VALUE;
        } else {
            return (int) res;
        }
    }

}
